package cn.xw.controller;

import cn.xw.utils.SimpleCaptchaUtils;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 测试EasyCaptcha验证码工具包
 *
 * @author AnHui OuYang
 * @version 1.0
 */
@Controller
public class EasyCaptchaController {

    private final StringRedisTemplate stringRedisTemplate;

    @Autowired
    public EasyCaptchaController(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /***
     * 获取验证码，直接写成图片信息（主要针对Session方式的。验证码的信息被存储到Session中）
     */
    @GetMapping("/captchaA")
    public void captchaA(HttpServletRequest request, HttpServletResponse response) {
        //构建验证码对象（及设置生成验证码的基本属性,）
        SimpleCaptchaUtils validateCodeUtils = SimpleCaptchaUtils.getSimpleCaptchaUtils();
        //validateCodeUtils.setBuiltInFonts(9);
        //validateCodeUtils.setBase64(true);
        //validateCodeUtils.setArithmeticLen(3);
        //生成一个带gif的闪图验证码
//        String s = validateCodeUtils.gifCaptchaSession(request, response);
        String s = validateCodeUtils.specCaptchaSession(request, response);
        System.out.println(s);

    }

    /***
     * 校验"/captchaA"生成的验证码
     * @return String
     */
    @GetMapping("/checkCaptchaA")
    public @ResponseBody String checkCaptchaA(HttpServletRequest request, HttpServletResponse response) {
        // 获取传入的code
        String code = request.getParameter("code");
        // 获取session信息
        HttpSession session = request.getSession();
        // 获取session存储的code
        String sessionCode = String.valueOf(session.getAttribute(SimpleCaptchaUtils.SESSION_ATTR_NAME));
        // 判断是否相同
        if (code.toLowerCase().equals(sessionCode)) {
            session.removeAttribute("code"); //删除验证码
            return "{'success':'验证码正确'}";
        } else {
            session.removeAttribute("code"); //删除验证码
            return "{'success':'验证码错误'}";
        }
    }

    /***
     * 获取验证码，适用与前后端分离，生成的验证码存储在redis中，按照key后期校验
     */
    @GetMapping("/captchaB")
    public @ResponseBody String captchaB(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //构建验证码对象（及设置生成验证码的基本属性,若想返回Base64的验证码则setBase64(true)即可）
        SimpleCaptchaUtils validateCodeUtils = SimpleCaptchaUtils.getSimpleCaptchaUtils();
        validateCodeUtils.setBuiltInFonts(8);
        validateCodeUtils.setBase64(true);
        //生成一个带gif的闪图验证码
        SimpleCaptchaUtils.CaptchaInfo codeInfo = validateCodeUtils.gifCaptchaSeparate(response);
        //在redis保存key和value，下次请求时需要携带key和value信息
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        //设置3分钟过期
        opsForValue.setIfAbsent(codeInfo.getCodeKey(), codeInfo.getCodeValue(), 3, TimeUnit.MINUTES);
        //非Base64的图片信息，所以我需要手动写出
        //codeInfo.getCaptcha().out(response.getOutputStream());
        return JSONObject.toJSONString(codeInfo);
    }

    /***
     * 校验"/captchaB"生成的验证码
     * @return String
     */
    @GetMapping("/checkCaptchaB")
    public @ResponseBody String checkCaptchaB(HttpServletRequest request, HttpServletResponse response) {
        // 获取前端传入的数据
        String codeKey = request.getParameter("codeKey");
        String code = request.getParameter("code");
        //获取redis存的验证码
        String codeRedis = stringRedisTemplate.opsForValue().get(codeKey);
        //校验（不区分大小写）
        if (code.equalsIgnoreCase(codeRedis)) {
            stringRedisTemplate.delete(codeKey);  //删除验证码
            return "{'success':'验证码正确'}";
        } else {
            stringRedisTemplate.delete(codeKey);  //删除验证码
            return "{'success':'验证码错误'}";
        }
    }
}
